from flask import Blueprint, request,jsonify,session

from pydantic import BaseModel, Field, EmailStr, constr
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import select
from applications.models.UserModel import Register, Login
from applications.sql_config import db
from flask_jwt_extended import jwt_required, get_jwt_identity,create_access_token

from applications.models.admin_user import User

from applications.functions.is_strong_password import is_strong_password
from applications.functions.is_valid_email import is_valid_email
from applications.functions.response import success_response,error_response

import config


app = config.anime_app
siwa = config.anime_siwa
siwa_tag = "用户相关操作"
group_name = "用户注册"
# bp = Blueprint('user', __name__, url_prefix='/user')
user = Blueprint('user',__name__)



# {email: "2337@qq.com", userName: "tea", password: "123456", confirmPassword: "123456"}
# @bp.post('/register')

@app.route('/api/user/register', methods=['POST'])
@siwa.doc(body= Register,tags=[siwa_tag], group=group_name)
def register():
    try:
       # 1. 提取数据
        data = request.get_json()
        params = data.get('params', {})
        email = params.get('email')
        userName = params.get('userName')
        password = params.get('password')
        confirm_password = params.get('confirmPassword')
        print(params)

        if not all([email, userName, password, confirm_password]):   
            return error_response(400, "所有字段均为必填项")
        
        if password != confirm_password:
            return error_response(400, "两次输入的密码不一致")

        if not is_valid_email(email):
            return error_response(400, "邮箱格式无效")

        # 基于User模型查询（需确保已正确定义User类）
        existing_user = db.session.query(User).filter_by(email=email).first()
        if existing_user:
            return error_response(400, "该邮箱已被注册")
        
        if not is_strong_password(password):
            return error_response(400, "密码需至少8位且包含大小写字母和数字")
        
        # 3. 唯一性校验
        existing_email = db.session.scalar(
            select(User).where(User.email == email)
        )
        if existing_email:
            return error_response(400, "该邮箱已被注册")
        
        existing_username = db.session.scalar(
            select(User).where(User.userName == userName)
        )
        if existing_username:
            return error_response(400, "用户名已被占用")
        
        # 4. 创建用户
        new_user = User(
            userName=userName,
            email=email,
            avatar='/static/images/default_avatar.png'  # 显式设置默认值
        )
        new_user.set_password(password)  # 密码哈希处理
        
        # 5. 数据库操作
        db.session.add(new_user)
        db.session.commit()
        
        # 6. 返回成功响应（隐藏敏感信息）
        return success_response(200, "注册成功", data={
            "user": {
                "userName": userName,
                "email": email,
                "avatar": new_user.avatar,
                "time": new_user.time.isoformat()  # 时间标准化格式
            }
        })

    except Exception as e:
        db.session.rollback()
        return error_response(500, f"服务器内部错误: {str(e)}")





@app.route('/api/user/login', methods=['POST'])
@siwa.doc(body=Login, tags=[siwa_tag], group=group_name)
def login():
    try:
        data = request.get_json()
        params = data.get('params', {})
        username = params.get('userName')  # 改为仅接收用户名
        password = params.get('password')
        
        # 1. 验证必填字段
        if not all([username, password]):
            return error_response(400, "用户名和密码为必填项")
        
        # 2. 仅通过用户名查询用户
        user = db.session.scalar(
            select(User).where(User.userName == username)  # 移除邮箱验证
        )
        
        # 3. 验证用户状态
        if not user:
            return error_response(400, "用户不存在")
        
        # 4. 安全哈希密码验证
        if not user.check_password(password):
            print(user.check_password(password))
            return error_response(400, "密码验证失败")
        
        # 5. 生成JWT令牌（代替session）
        token = create_access_token(
            identity=str(user.id),          #JWT的Payload部分包含标准声明字段sub（Subject），RFC 7519标准要求其值必须是字符串类型
            additional_claims={  # 添加自定义声明
                "username": user.userName,
                "email": user.email
            }
        )
        
        # 6. 返回用户信息和JWT
        return success_response(200, "登录成功", data={
                "userName": user.userName,
                "avatar": user.avatar,
                "email": user.email,
                "token": token  # 返回JWT给前端
            })
        
    except Exception as e:
        app.logger.error(f"登录异常: {str(e)}")
        return error_response(500, f"登录服务异常: {str(e)}")



@app.route('/api/user/userInfo', methods=['GET'])
@siwa.doc(tags=[siwa_tag], group=group_name)
@jwt_required()  # 添加JWT认证装饰器[3,4](@ref)
def get_user_info():
    try:
        # 1. 从JWT令牌获取用户身份
        current_user_id = get_jwt_identity()
        
        # 2. 查询用户信息
        user = db.session.scalar(
            select(User).where(User.id == current_user_id)
        )
        
        # 3. 验证用户存在性
        if not user:
            return error_response(404, "用户不存在或已被删除")
        
        # 4. 构建安全响应数据（排除敏感字段）
        user_data = {
            "userName": user.userName,
            "avatar": user.avatar,
            "email": user.email,
        }
        
        # 5. 返回用户信息
        return success_response(200, "用户信息获取成功", data=user_data)
        
    except Exception as e:
        app.logger.error(f"获取用户信息异常: {str(e)}")
        return error_response(500, "用户信息查询服务异常")